package com.KegController.BrewCoder;

import com.agentx3r.lib.USBControl;
import com.android.future.usb.UsbManager;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;

import android.util.Log;
import android.widget.Toast;

public class adkService extends Service { // implements Runnable {

	private static final String TAG = "adkService";
	private static final String adkServiceMessage = "BrewCoder.KegController.ServiceMessage";
	public static final String adkServiceShuttingDown = "BrewCoder.KegController.ServiceStopping";

	private Handler UIHandler = new Handler();
	private USBControlServer usbConnection;
	
	public Intent intent;

	private Timer updateNoteTimer;
	private boolean adkIsConnected = false;

	final static int myID = 926;

	boolean celsius = false;

	// This is the object that receives interactions from clients. See
	// RemoteService for a more complete example.
	private final IBinder mBinder = new adkBinder();

	// Notification values
	private NotificationManager nm;

	SharedPreferences preferences;
	kegFridge kegger1 = new kegFridge();
	NumberFormat formatter = new DecimalFormat("###.00");

	// Bind (Connect with main activity by returning the adkservice intent
	public class adkBinder extends Binder {
		adkService getService() {
			return adkService.this;
		}
	}

	@Override
	public IBinder onBind(Intent arg0) {
		Log.d(TAG, "onBind");
		return mBinder;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		Log.d(TAG, "onCreate");
		nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
		
		preferences = PreferenceManager.getDefaultSharedPreferences(this);
		updateCelsius();
		
		updateNoteTimer = new Timer();

		setupUSB();

		IntentFilter filter = new IntentFilter(
				UsbManager.ACTION_USB_ACCESSORY_DETACHED);
		registerReceiver(myReceiver, filter);

		Toast.makeText(this, R.string.ADK_service_started, Toast.LENGTH_SHORT)
				.show();

		updateNotification();

	}

	// Intent broadcast receiver for Service broadcast and ask attachment
	private final BroadcastReceiver myReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {

			String action = intent.getAction();
			Log.d(TAG, "USB unplugged stop service" + action);
			Intent BroadCastAdkServiceMesages = new Intent();
			BroadCastAdkServiceMesages.setAction(adkServiceShuttingDown);
			sendBroadcast(BroadCastAdkServiceMesages);
			adkService.this.stopSelf();

		}
	};

	@Override
	public void onDestroy() {
		super.onDestroy();

		updateNoteTimer.cancel();

		unregisterReceiver(myReceiver);

		Toast.makeText(this, R.string.ADK_service_stopped, Toast.LENGTH_SHORT)
				.show();
		nm = null;
		Log.d(TAG, "onDestroy");
	}

	void updateNotification() {
		CharSequence title = "Keg Controller";
		int icon = R.drawable.icon_keg;
		CharSequence ticketText;
		
		if (adkIsConnected)
			ticketText = "Interior Temp: "
					+ getCurrentInteriorTempFormatted();
		else
			ticketText = "ADK Not Connected";

		Notification notification = new Notification(icon, title,
  		System.currentTimeMillis());
		
		PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
				new Intent(this, KegControllerActivity.class), 0);
		

  		notification.setLatestEventInfo(this, ticketText,
  				title, contentIntent);
  		nm.notify(0, notification);
		
	
	}


	public void sendCommand(int command, int temp) {
		byte[] buffer = new byte[4];
		if (adkIsConnected) {
			switch (command) {
			case (1):
				buffer[0] = (byte) 1;
				// if(sendMessages.isAndroidOverride())
				buffer[1] = (byte) 0x01;
				buffer[2] = (byte) 0x00;

				break;
			case (2):
				buffer[0] = (byte) 2;
				buffer[1] = (byte) (temp >> 8);
				buffer[2] = (byte) (temp & 0xff);
				Log.d(TAG, "Temp Sent");
				break;
			case (3):
				buffer[0] = (byte) 3;
				if (temp == 1)
					buffer[1] = (byte) 1;
				else
					buffer[1] = (byte) 0;
				buffer[2] = (byte) 2;
				break;
				
			case (4):
				buffer[0] = (byte) 4;
			buffer[1] = (byte) (temp >> 8);
			buffer[2] = (byte) (temp & 0xff);
			
			/*if (temp == 1)
				buffer[1] = (byte) 1;
			else
				buffer[1] = (byte) 0;
			buffer[2] = (byte) 2;*/
				break;
			case (5):
				buffer[0] = (byte) 5;
			buffer[1] = (byte) (temp >> 8);
			buffer[2] = (byte) (temp & 0xff);
				break;
			
			default:
				buffer[0] = (byte) 255;
				buffer[1] = (byte) 3;
				buffer[2] = (byte) 2;
				break;
			}
			usbConnection.send(buffer);
		}
	}

	private void setupUSB() {

		usbConnection = new USBControlServer(UIHandler);

	}

	private void closeUSB() {

		usbConnection.closeAccessory();
		usbConnection.destroyReceiver();

	}

	public class USBControlServer extends USBControl {

		public USBControlServer(Handler ui) {
			super(getApplicationContext(), ui);
		}

		@Override
		public void onReceive(byte[] msg) {
			int curTemp = composeInt(msg[2], msg[3]);
			int setTemp = composeInt(msg[4], msg[5]);
			Log.d(TAG, "currentTemp: " + curTemp);
			kegger1.setCurrentInteriorTemp(curTemp);
			kegger1.setCurrentSetTemp(setTemp);

			// Tell the app we have new data!!!
			Intent BroadCastAdkServiceMesages = new Intent();
			BroadCastAdkServiceMesages.setAction(adkServiceMessage);
			sendBroadcast(BroadCastAdkServiceMesages);

		}

		@Override
		public void onNotify(String msg) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onConnected() {
			// TODO Auto-generated method stub
			adkIsConnected = true;
			updateNoteTimer.scheduleAtFixedRate(new updateNoteTimeTask(), 500,
					1000);
		}

		@Override
		public void onDisconnected() {
			adkIsConnected = false;
			updateNoteTimer.cancel();
			updateNotification();

		}
	}

	private int composeInt(byte hi, byte lo) {
		int val = (int) hi & 0xff;
		val *= 256;
		val += (int) lo & 0xff;
		return val;
	}

	class updateNoteTimeTask extends TimerTask {
		public void run() {
			updateNotification();
		}
	}
	
	public void setCurrentSetTemp(double Temp) {
			if(celsius)
			kegger1.setCurrentSetTemp(Temp);
			kegger1.setCurrentSetTemp((double)convertFtoC(Temp));
	}

	public double getCurrentSetTemp() {
		return kegger1.getCurrentSetTemp();
	}
	
	public String getCurrentInteriorTempFormatted() {
		if (celsius)
			return formatter.format(kegger1.getCurrentInteriorTemp()/100);

			return formatter.format(convertCtoF(kegger1.getCurrentInteriorTemp()/100));
			
	}
	
	public String getCurrentSetTempFormatted(){
		if (celsius)
			return formatter.format(kegger1.getCurrentSetTemp()/100);

			return formatter.format(convertCtoF(kegger1.getCurrentSetTemp())/100);
	}
	private String displayFormattedText(double temp, boolean celsius){
		if(celsius)
			return formatter.format(temp);
			return formatter.format(convertCtoF(temp));
	}

	private double convertCtoF(double tmp) {
		return (tmp * 1.8) + 32;
	}

	private double convertFtoC(double tmp) {
		return (tmp - 32) * (.5555555);
	}

	public boolean isCelsius() {
		return celsius;
	}

	public void updateCelsius() {
		celsius = preferences.getBoolean("displayCelsius", false);
	}
}